package com.mall.users.service;

import cn.hutool.core.collection.CollUtil;
import com.mall.commons.exception.BusinessException;
import com.mall.commons.utils.Constants;
import com.mall.commons.utils.IpUtil;
import com.mall.commons.utils.JwtUtils;
import com.mall.model.domain.*;
import com.mall.model.vo.CommonPage;
import com.mall.model.vo.UmsAdminVo;
import com.mall.users.mapper.UmsAdminMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import sun.net.util.IPAddressUtil;

import java.util.*;

@Service
public class UmsAdminService {


    @Autowired
    private UmsAdminMapper umsAdminMapper;

    @Autowired
    private UmsMenuService umsMenuService;

    @Autowired
    private UmsRoleMenuRelationService umsRoleMenuRelationService;

    @Autowired
    private UmsRoleService umsRoleService;

    @Autowired
    private UmsAdminRoleRelationService umsAdminRoleRelationService;

    @Autowired
    private UmsAdminLoginLogService umsAdminLoginLogService;

    /**
     * 用户登录
     * @param umsAdmin
     * @param userAgent
     * @param ip
     * @return
     */
    public Map login(UmsAdmin umsAdmin, String userAgent, String ip) {
        UmsAdmin loginUmsAdmin = umsAdminMapper.selectByUsername(umsAdmin.getUsername());
        if (loginUmsAdmin == null) {
            //用户不存在
            throw new BusinessException("用户不存在");
        }
        if (loginUmsAdmin.getStatus() != 1) {
            //用户被禁用
            throw new BusinessException("用户被禁用");
        }
        //Spring Security密码解密
        BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
        if (!bcryptPasswordEncoder.matches(umsAdmin.getPassword(), loginUmsAdmin.getPassword())) {
            //密码错误
            throw new BusinessException("密码错误");
        }
        //登录成功,返回token
        Map tokenMap = new HashMap();
        tokenMap.put("id",umsAdmin.getId());
        tokenMap.put("username",umsAdmin.getUsername());
        String token = JwtUtils.getToken(tokenMap);
        Map retMap = new HashMap();
        retMap.put("token",token);
        retMap.put("tokenHead", Constants.TOKEN_PREFIX);

        //保存用户登录日志
        UmsAdminLoginLog log = new UmsAdminLoginLog();
        log.setAdminId(loginUmsAdmin.getId());
        log.setIp(ip);
        log.setCreateTime(new Date());
        //log.setAddress(IpUtil.getIpInfo(ip));
        log.setUserAgent(userAgent);
        umsAdminLoginLogService.save(log);
        return retMap;
    }

    /**
     * 根据用户名查询用户信息
     * @param name
     * @return
     */
    public UmsAdminVo info(String name) {
        UmsAdmin umsAdmin = umsAdminMapper.selectByUsername(name);
        UmsAdminVo vo = new UmsAdminVo();
        if (umsAdmin == null) {
            //用户不存在
            throw new BusinessException("用户不存在");
        }
        BeanUtils.copyProperties(umsAdmin, vo);
        List<UmsAdminRoleRelation> adminRoleRelationList = umsAdminRoleRelationService.findByAdminId(umsAdmin.getId());
        if (CollUtil.isEmpty(adminRoleRelationList)) {
            return vo;
        }
        List<Long> roleIds = CollUtil.getFieldValues(adminRoleRelationList, "roleId", Long.class);
        List<UmsRole> roleList = umsRoleService.findByIds(roleIds);
        if (CollUtil.isEmpty(roleList)) {
            return vo;
        }
        List<String> names = CollUtil.getFieldValues(roleList,"name",String.class);
        vo.setRoles(names);
        List<Long> menuIds = umsRoleMenuRelationService.findByRoleIds(roleIds);
        if (CollUtil.isEmpty(menuIds)) {
            return vo;
        }
        List<UmsMenu> menus = umsMenuService.findByIds(menuIds);
        if (CollUtil.isEmpty(menus)) {
            return vo;
        }
        vo.setMenus(menus);
        return vo;
    }

    /**
     * 分页查询用户列表
     * @param pageNum
     * @param pageSize
     * @param keyword
     * @return
     */
    public CommonPage list(Integer pageNum, Integer pageSize, String keyword) {
        Integer count = umsAdminMapper.selectCount(keyword);
        List<UmsAdmin> umsAdminList = umsAdminMapper.selectByPage(pageNum,pageSize,keyword);
        return new CommonPage(pageNum, pageSize, count, umsAdminList);
    }

    /**
     * 删除用户
     * @param id
     */
    @Transactional
    public void delete(Long id) {
        // 根据用户id删除ums_admin表数据
        umsAdminMapper.deleteById(id);
        // 根据用户id删除ums_admin_role_relation表信息
        umsAdminRoleRelationService.deleteByAdminId(id);
    }

    /**
     * 用户注册
     * @param umsAdmin
     */
    public UmsAdmin register(UmsAdmin umsAdmin) {
        UmsAdmin admin = umsAdminMapper.selectByUsername(umsAdmin.getUsername());
        if (admin!= null) {
            //用户名已存在
            throw new BusinessException("用户名已存在");
        }
        String regex = "\\w+(\\.\\w)*@\\w+(\\.\\w{2,3}){1,3}";
        if (!umsAdmin.getEmail().matches(regex)) {
            //邮箱格式不正确
            throw new BusinessException("邮箱格式不正确");
        }
        umsAdmin.setPassword(new BCryptPasswordEncoder().encode(umsAdmin.getPassword()));
        umsAdmin.setCreateTime(new Date());
        umsAdminMapper.add(umsAdmin);
        return umsAdmin;
    }

    /**
     * 获取指定用户的角色
     * @param adminId
     * @return
     */
    public List<UmsRole> getRole(Long adminId) {
        List<UmsAdminRoleRelation> list = umsAdminRoleRelationService.findByAdminId(adminId);
        if (CollUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        List<Long> roleIds = CollUtil.getFieldValues(list, "roleId", Long.class);
        return umsRoleService.findByIds(roleIds);
    }

    /**
     * 修改或保存用户的权限关系
     * @param adminId
     * @return
     */
    public Integer updateRole(Long adminId, List<Long> roleIds) {
        // 根据用户id去查权限
        List<UmsAdminRoleRelation> list = umsAdminRoleRelationService.findByAdminId(adminId);
        if (CollUtil.isNotEmpty(list)) {
           //存在用户和角色关系,则根据用户id删除
            umsAdminRoleRelationService.deleteByAdminId(adminId);

        }
        // 不存在就直接新增(批量)
        List<UmsAdminRoleRelation> relationList = new ArrayList<>();
        for (Long roleId : roleIds) {
            UmsAdminRoleRelation umsAdminRoleRelation = new UmsAdminRoleRelation();
            umsAdminRoleRelation.setAdminId(adminId);
            umsAdminRoleRelation.setRoleId(roleId);
            relationList.add(umsAdminRoleRelation);
        }
        umsAdminRoleRelationService.save(relationList);
        // 返回权限的数量
        return relationList.size();
    }

    /**
     * 修改用户信息
     * @param umsAdmin
     */
    public void update(UmsAdmin umsAdmin) {
        UmsAdmin admin = umsAdminMapper.selectByUsername(umsAdmin.getUsername());
        if (admin!= null && admin.getId() != umsAdmin.getId()) {
            //用户名已存在
            throw new BusinessException("用户名已存在");
        }
        String regex = "\\w+(\\.\\w)*@\\w+(\\.\\w{2,3}){1,3}";
        if (!umsAdmin.getEmail().matches(regex)) {
            //邮箱格式不正确
            throw new BusinessException("邮箱格式不正确");
        }
        umsAdmin.setPassword(new BCryptPasswordEncoder().encode(umsAdmin.getPassword()));
        umsAdminMapper.update(umsAdmin);
    }

    /**
     * 修改指定用户密码
     * @param username
     * @param oldPassword
     * @param newPassword
     */
    public void updatePassword(String username, String oldPassword, String newPassword) {
        UmsAdmin umsAdmin = umsAdminMapper.selectByUsername(username);
        if (umsAdmin == null) {
            //用户不存在
            throw new BusinessException("用户不存在");
        }
        BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
        if (!bcryptPasswordEncoder.matches(oldPassword, umsAdmin.getPassword())) {
            //密码错误
            throw new BusinessException("密码错误");
        }
        umsAdmin.setPassword(new BCryptPasswordEncoder().encode(newPassword));
        umsAdminMapper.update(umsAdmin);
    }

    /**
     * 修改指定用户的状态
     * @param id
     * @param status
     */
    public void updateStatus(Long id, Integer status) {
        UmsAdmin umsAdmin = umsAdminMapper.selectById(id);
        if (umsAdmin == null) {
            //用户不存在
            throw new BusinessException("用户不存在");
        }
        umsAdmin.setStatus(status);
        umsAdminMapper.update(umsAdmin);
    }

    /**
     * 获取指定用户的信息
     * @return
     */
    public UmsAdmin findById(Long id) {
        return umsAdminMapper.selectById(id);
    }
}
